{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualize the Environment Model\n",
    "\n",
    "Evaluate and visualize the performance of the environment model by seeing it visualize future states while a A2C agent plays the game.\n",
    "\n",
    "First start off with some imports."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from env_model import make_env, create_env_model\n",
    "from common.multiprocessing_env import SubprocVecEnv\n",
    "from pacman_util import num_pixels, mode_rewards, pix_to_target, rewards_to_target\n",
    "from a2c import get_actor_critic, CnnPolicy\n",
    "from i2a import convert_target_to_real\n",
    "from common.minipacman import MiniPacman  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from IPython.display import clear_output\n",
    "import matplotlib.pyplot as plt\n",
    "import time\n",
    "%matplotlib inline\n",
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next create the environments we will use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "nenvs = 16\n",
    "nsteps = 5\n",
    "envs = [make_env() for i in range(nenvs)]\n",
    "envs = SubprocVecEnv(envs)\n",
    "\n",
    "ob_space = envs.observation_space.shape\n",
    "ac_space = envs.action_space\n",
    "num_actions = envs.action_space.n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, go ahead and test the environment model in minipacman. This will use the A2C agent to play the game and the environment model to predict future states and rewards. Note that you should replace the locations of my weights with the locations of your own saved weights. This will visualize the imagined and real rewards and game states from the environment model. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n/UtXAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f11c19291d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "env = MiniPacman('regular', 1000)\n",
    "done = False\n",
    "states = env.reset()\n",
    "num_actions = ac_space.n\n",
    "nw, nh, nc = ob_space\n",
    "print('observation space', ob_space)\n",
    "print('number of actions', num_actions)\n",
    "steps = 0\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    # Load the actor\n",
    "    with tf.variable_scope('actor'):\n",
    "        actor_critic = get_actor_critic(sess, nenvs, nsteps, ob_space,\n",
    "                ac_space, CnnPolicy, should_summary=False)\n",
    "    actor_critic.load('weights/model_100000.ckpt')\n",
    "    \n",
    "    # Load the critic\n",
    "    with tf.variable_scope('env_model'): \n",
    "        env_model = create_env_model(ob_space, num_actions, num_pixels,\n",
    "                len(mode_rewards['regular']), should_summary=False)\n",
    "\n",
    "    save_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='env_model')\n",
    "    loader = tf.train.Saver(var_list=save_vars)\n",
    "    loader.restore(sess, 'weights/env_model.ckpt')\n",
    "    \n",
    "    while not done and steps < 20:\n",
    "        steps += 1\n",
    "        actions, _, _ = actor_critic.act(np.expand_dims(states, axis=0))\n",
    "\n",
    "        onehot_actions = np.zeros((1, num_actions, nw, nh))\n",
    "        onehot_actions[range(1), actions] = 1\n",
    "        # Change so actions are the 'depth of the image' as tf expects\n",
    "        onehot_actions = onehot_actions.transpose(0, 2, 3, 1)\n",
    "\n",
    "        s, r = sess.run([env_model.imag_state, \n",
    "                                        env_model.imag_reward], \n",
    "                                       feed_dict={\n",
    "                env_model.input_states: np.expand_dims(states, axis=0),\n",
    "                env_model.input_actions: onehot_actions\n",
    "            })\n",
    "        \n",
    "        s, r = convert_target_to_real(1, nw, nh, nc, s, r)\n",
    "        \n",
    "        states, reward, done, _ = env.step(actions[0])\n",
    "\n",
    "        clear_output(True)\n",
    "        plt.figure(figsize=(10,3))\n",
    "        plt.subplot(131)\n",
    "        plt.title(\"Imagined (Reward %i)\" % r[0])\n",
    "        plt.imshow(s[0])\n",
    "        plt.subplot(132)\n",
    "        \n",
    "        plt.title(\"Actual (Reward %i)\" % reward)\n",
    "        plt.imshow(states)\n",
    "        plt.show()\n",
    "        time.sleep(0.1)\n"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
